#include "gkt_debug.h"
#include "gkt_window.h"
#include "gkt_fps.h"
#include "gkt_os.h"

#if defined(GKT_CONFIG_FPS_ENABLE) && GKT_CONFIG_FPS_ENABLE
#if 0
static uint8_t	*fps_buffer;
static uint32_t finger_leave;
static uint32_t mask_flag;
static uint32_t mask_acquire;
static gkt_thread_t fps_handle_task;
static gkt_semaphore_t irq_semaphore_t;
static gkt_semaphore_t leave_finger_semaphore_t;
//static gkt_semaphore_t mask_semaphore_t;
#endif
#if 0
static void gkt_fps_callback(uint32_t status)
{
	gkt_trace("window_fps: status = 0x%x\n", status);
	if (GKT_FPS_ST_FINGER_PRESS == status) {
		gkt_semaphore_release(irq_semaphore_t);
	}
}

void gkt_fps_mask_release(void)
{
	if(mask_acquire == 1){
		gkt_semaphore_release(mask_semaphore_t);
	}
}

static void gkt_fps_wait_finger_leave(void)
{
	//uint32_t	time_out_finger = 0;
	int	ret_val;
	while(1){
		gkt_thread_sleep(100);
		ret_val = gkt_fpsensor_is_finger_on();
		if(ret_val == GKT_FPS_ST_FINGER_LEAVE){
			break;
		}
	}
}

void gkt_fps_capture_task(void *param)
{
	int os_status,retval;
	gkt_event_s event;


	while(1){
		//finger_leave
		mask_acquire = 1;			
		os_status = gkt_semaphore_acquire(mask_semaphore_t, GKT_INFINITE);
		mask_acquire = 0;
		if((os_status != 0) || mask_flag){
			continue;
		}
		
		retval = gkt_fpsensor_detect();
		os_status = gkt_semaphore_acquire(irq_semaphore_t, GKT_INFINITE);
		if(os_status != 0){
			continue;
		}		
		if(mask_flag){
			continue;
		}
		if(fps_buffer != NULL){
			gkt_fpsensor_destroy_image(fps_buffer);
			fps_buffer = NULL;
		}	
		fps_buffer = gkt_fpsensor_create_image();
		if(fps_buffer == NULL)
			continue;

		retval = gkt_fpsensor_capture_image(fps_buffer,GKT_INFINITE);
		event.flags = 0;
		event.major_type = GKT_EVENT_FPS;
		event.minor_type = 0;
		event.data[0] = retval;
		event.id = GKT_WINDOW_ID_ACTIVE;
		retval = gkt_event_put(&event,GKT_IMMEDIATELY);
		gkt_info("____fps_capture__%d\n",retval);
		if(retval == GKT_ENOTOPEN){
			gkt_fpsensor_destroy_image(fps_buffer);
			gkt_thread_destroy(fps_handle_task);
			return;
		}
		mask_acquire = 1;
		gkt_fps_wait_finger_leave();
		//gkt_thread_sleep(100);
	}
}

void gkt_fps_task_handle(void)
{
	int retval;

	fps_buffer = NULL;
	finger_leave = GKT_FPS_ST_FINGER_LEAVE;
	mask_flag = 0;
	retval = gkt_fpsensor_init();
	if(retval != GKT_SUCCESS){
		return;
	}

	irq_semaphore_t = gkt_semaphore_create(1, 0);
	if(!irq_semaphore_t){
		return;	
	}

	leave_finger_semaphore_t = gkt_semaphore_create(1, 0);
	if(!leave_finger_semaphore_t){
		return;	
	}

	mask_semaphore_t = gkt_semaphore_create(1, 0);
	if(!mask_semaphore_t){
		return;	
	}

	fps_handle_task = gkt_thread_create(gkt_fps_capture_task, NULL, 
					GKT_THREAD_PRIORITY_NORMAL, 0x1000, NULL);
	if(!fps_handle_task){
		return;
	}
	gkt_semaphore_release(mask_semaphore_t);
}

int gkt_fps_init(void)
{
	gkt_fpsensor_config_attr_s attr;

	attr.callback = gkt_fps_callback;
	gkt_fpsensor_config(&attr);
	gkt_unused(gkt_fps_callback);
	gkt_fps_task_handle();	
	return GKT_SUCCESS;
}

void gkt_fps_mask(int masked, uint32_t flags)
{
	gkt_unused(flags);

	if(masked){
		mask_flag = 1;
	}
	else{
		mask_flag = 0;
		if(mask_acquire == 1){
		gkt_fps_mask_release();
		}
	}
}
#elif 0
static void gkt_fps_callback(uint32_t status)
{
	gkt_trace("window_fps: status = 0x%x\n", status);
	if (GKT_FPS_ST_FINGER_PRESS == status) {
		gkt_semaphore_release(irq_semaphore_t);
	}
}

void gkt_fps_mask_release(void)
{

}

static void gkt_fps_wait_finger_leave(void)
{
	//uint32_t	time_out_finger = 0;
	int	ret_val;
	while(1){
		gkt_thread_sleep(100);
		ret_val = gkt_fpsensor_is_finger_on();
		if(ret_val == GKT_FPS_ST_FINGER_LEAVE){
			break;
		}
	}
}

void gkt_fps_capture_task(void *param)
{
	int os_status,retval;
	gkt_event_s event;

	mask_flag = 0;
	while(1){
		if(mask_flag == 0)
			gkt_fpsensor_detect();
		mask_acquire = 1;
		os_status = gkt_semaphore_acquire(irq_semaphore_t, GKT_INFINITE);
		mask_acquire = 0;
		if(os_status != 0){
			continue;
		}
		if(mask_flag == 1){
			continue;
		}
		if(fps_buffer != NULL){
			gkt_fpsensor_destroy_image(fps_buffer);
			fps_buffer = NULL;
		}	
		fps_buffer = gkt_fpsensor_create_image();
		if(fps_buffer == NULL)
			continue;

		retval = gkt_fpsensor_capture_image(fps_buffer,GKT_INFINITE);
		event.flags = 0;
		event.major_type = GKT_EVENT_FPS;
		event.minor_type = 0;
		event.data[0] = retval;
		event.id = GKT_WINDOW_ID_ACTIVE;
		retval = gkt_event_put(&event,GKT_IMMEDIATELY);
		gkt_info("____fps_capture__%d\n",retval);
		if(retval == GKT_ENOTOPEN){
			gkt_fpsensor_destroy_image(fps_buffer);
			gkt_thread_destroy(fps_handle_task);
			return;
		}
		mask_acquire = 0;
		gkt_fps_wait_finger_leave();
		//gkt_thread_sleep(100);
	}
}

void gkt_fps_task_handle(void)
{
	int retval;

	fps_buffer = NULL;
	finger_leave = GKT_FPS_ST_FINGER_LEAVE;
	//mask_flag = 0;
	retval = gkt_fpsensor_init();
	if(retval != GKT_SUCCESS){
		return;
	}

	irq_semaphore_t = gkt_semaphore_create(1, 0);
	if(!irq_semaphore_t){
		return;	
	}

	leave_finger_semaphore_t = gkt_semaphore_create(1, 0);
	if(!leave_finger_semaphore_t){
		return;	
	}

	//mask_semaphore_t = gkt_semaphore_create(1, 0);
	//if(!mask_semaphore_t){
	//	return;	
	//}

	fps_handle_task = gkt_thread_create(gkt_fps_capture_task, NULL, 
					GKT_THREAD_PRIORITY_NORMAL, 0x1000, NULL);
	if(!fps_handle_task){
		return;
	}
	//gkt_semaphore_release(mask_semaphore_t);
}

int gkt_fps_init(void)
{
	gkt_fpsensor_config_attr_s attr;

	attr.callback = gkt_fps_callback;
	gkt_fpsensor_config(&attr);
	gkt_unused(gkt_fps_callback);
	gkt_fps_task_handle();	
	return GKT_SUCCESS;
}

void gkt_fps_mask(int masked, uint32_t flags)
{
	gkt_unused(flags);

	if(mask_acquire == 1){
		if(masked){
			mask_flag = 1;
			gkt_fpsensor_enter_idle();
		}
		else{
			mask_flag = 0;
			gkt_fpsensor_detect();
		}
	}
	else{
		if(masked){
			mask_flag = 1;
		}
		else{
			mask_flag = 0;
		}
	}
}
#else
void gkt_fps_mask_release(void)
{
	gkt_fpsensor_detect();
}

static void fps_callback(uint32_t status)
{
	gkt_event_s event;
	int retval;

	gkt_trace("window_fps: status = 0x%x\n", status);
	if (GKT_FPS_ST_FINGER_PRESS == status) {
		event.window_id = GKT_WINDOW_ID_ACTIVE;
		event.flags = 0;
		event.major_type = GKT_EVENT_FPS;
		event.minor_type = GKT_FPS_FINGER_PRESS;
		retval = gkt_event_put(&event, GKT_IMMEDIATELY);
		if (__UNLIKELY(retval != GKT_SUCCESS))
			gkt_error("window_fps: put event failed %d\n", retval);
	}
}

void gkt_fps_mask(int masked, uint32_t flags)
{
	gkt_unused(flags);

	if (masked)
		gkt_fpsensor_enter_idle();
	else
		gkt_fpsensor_detect();
}

int gkt_fps_init(void)
{
	gkt_fpsensor_config_attr_s attr;

	attr.callback = fps_callback;
	
	gkt_fpsensor_init();
	return gkt_fpsensor_config(&attr);
}
#endif
#else

#define gkt_fps_init	NULL
#define gkt_fps_mask	NULL

#endif

#define gkt_fps_event_handler	NULL

GKT_EVENT_DESC_DEFINE(FPS, fps);

